1. Introduction
It is now possible to temporarily make a user administrator and/or assign
roles dynamically to the user.
The modifications are performed on a UserItem object
before logging in, and they are not persisted to the security database.
They are only persisted as long as the user is logged in. When the user
logs out, or his session expires, the modifications are lost.
2. Making editor administrator
For example, to login the user 'editor' with administrative rights, you can use the following approach:
Domain domain = Sitecore.Context.Domain;
UserItem user = domain.GetUser("editor");
user.RuntimeSettings.IsAdministrator = true;
domain.Login(user);
After this code is run, the current user will be 'editor', and he will have administrative rights.
3. Adding roles dynamically
To add roles dynamically, use the following:
Domain domain = Sitecore.Context.Domain;
UserItem user = domain.GetUser("editor");
RoleItem role = domain.GetRole("webmasters");
user.RuntimeSettings.AddRole(role.ID);
domain.Login(user);
The 'editor' user will now be logged in as a member of the 'webmasters' role. You can check this by using the IsInRole() method on the user:
bool ok = user.IsInRole(role.ID);
4. Removing roles dynamically
Role assignments can also be removed dynamically. Normally, the 'editor' user is a member of the 'editors' role. Use the following code to temporarily remove that membership:
Domain domain = Sitecore.Context.Domain;
UserItem user = domain.GetUser("editor");
RoleItem role = domain.GetRole("editors");
user.RuntimeSettings.RemoveRole(role.ID);
domain.Login(user);
Now the 'editor' is logged in without the 'editors' membership.
Note that modifications to a users admin and roles status must be done prior to logging in.
5. Re-login user
If you wish to change the assignments after login, you must re-login the user. The following code shows an example:
string userName = "editor";
string password = "secret";
Domain domain = Sitecore.Context.Domain;
domain.Login(userName, password);
UserItem editorUser = domain.CurrentUser;
editorUser.RuntimeSettings.IsAdministrator = true;
domain.Login(editorUser);
In the example above the user is first logged in using a user name and password, and then the resulting user instance is modified and logged in again.
The reason you need to login again is that the runtime state of the user is only persisted during login. Therefore, if you do not login, the dynamic settings will disappear when the current page request ends.
The dynamic user state is persisted to the client data store that we use instead of session variables. The client data store makes it possible to maintain state data across page requests (even on server farms). But that's another story...
6. Creating A Virtual user
It is possible to create user objects in memory that do not physically exist in the security database. The user objects can be assigned administrative rights, roles etc. and can be used for login.
Once a virtual user has been logged in, it is used by the system as if it was a 'real' user. Thus, API code that has special security needs can use virtual users to accomplish these.
An example of creating a virtual user:
ID myUserID = ID.NewID;
string myUserName = "Virt";
UserItem myUser = Context.Domain.BuildVirtualUser(myUserID, myUserName);
using(new EditContext(myUser.InnerItem))
{
myUser.IsAdministrator = true;
}
Context.Domain.Login(myUser);
Item item = GetSomeProtectedItem(...);
7. Switching security
Sometimes, you may not want to actually log the virtual user in. If you only need the user in a specific context, you can use the SecuritySwitcher class:
ID myUserID = ID.NewID;
string myUserName = "Virt";
UserItem myUser = Context.Domain.BuildVirtualUser(myUserID, myUserName);
using(new EditContext(user.InnerItem))
{
user.IsAdministrator = true;
}
using (new SecuritySwitcher(myUser)) {
Item item = GetSomeProtectedItem(...);
...
}
The security switcher causes Context.User to change to myUser inside the using block. After leaving the block, Context.User is restored to its previous value.